package com.test.pdproject.controller;

import com.test.pdproject.auth.MyShiroRealm;
import com.test.pdproject.constant.PageData;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @ClassName lisaisai
 * @Descirption 登录、登出控制类
 * @Author Administrator
 * @Date 2018/9/14 15:02
 * @Version 1.0
 **/
@Controller
@RequestMapping(value = "/user")
public class LoginController extends BaseController {
    private static final Logger log= Logger.getLogger(MyShiroRealm.class);
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String userLogin(ModelAndView model, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        PageData pageData = this.getPageData();
        if (pageData == null) {
            return "view/login";
        }
        if (StringUtils.isBlank(pageData.getString("loginName")) || StringUtils.isBlank(pageData.getString("password"))) {
            log.info("用户名或密码为空! ");
            redirectAttributes.addFlashAttribute("message", "用户名或密码为空!");
            //这样就相当于：return "redirect:/tologin?message=用户名或密码为空!"
            return "redirect:tologin";
        }
        String account = pageData.get("loginName").toString();
        String password = pageData.get("password").toString();
        //验证用户是否存在  密码是否正确

        // 认证通过生成token
        UsernamePasswordToken token = new UsernamePasswordToken(account, password, false);
        Subject currentUser = SecurityUtils.getSubject();
        System.out.println("TOKEN"+token);
        try {
            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查  
            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应  
            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法  
            log.info("对用户[" + account + "]进行登录验证..验证开始");
            currentUser.login(token);
            log.info("对用户[" + account + "]进行登录验证..验证通过");
        } catch (UnknownAccountException uae) {
            log.info("对用户[" + account + "]进行登录验证..验证未通过,未知账户");
            redirectAttributes.addFlashAttribute("message", "未知账户");
        } catch (IncorrectCredentialsException ice) {
            log.info("对用户[" + account + "]进行登录验证..验证未通过,错误的凭证");
            redirectAttributes.addFlashAttribute("message", "密码不正确");
        } catch (LockedAccountException lae) {
            log.info("对用户[" + account + "]进行登录验证..验证未通过,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "账户已锁定");
        } catch (ExcessiveAttemptsException eae) {
            log.info("对用户[" + account + "]进行登录验证..验证未通过,错误次数大于5次,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数大于5次,账户已锁定");
        } catch (DisabledAccountException sae) {
            log.info("对用户[" + account + "]进行登录验证..验证未通过,帐号已经禁止登录");
            redirectAttributes.addFlashAttribute("message", "帐号已经禁止登录");
        } catch (AuthenticationException ae) {
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
            log.info("对用户[" + account + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
        }
        //验证是否登录成功
        if (currentUser.isAuthenticated()) {
            log.info("用户[" + account + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
            //把当前用户放入session
            Session session = currentUser.getSession();
            PageData tUser = new PageData();
            tUser.put("username", "yanxibaba");
            tUser.put("UserId", "1");
            session.setAttribute("currentUser", tUser);
            return "welcome";
        } else {
            token.clear();
            return "redirect:tologin";
        }
    }

    //配合shiro配置中的默认访问url
    @RequestMapping(value = "/tologin", method=RequestMethod.GET)
    public ModelAndView getLogin(HttpServletRequest request, ModelAndView model, HttpSession session, HttpServletResponse response) {
        String message = request.getParameter("message");
        if(message!=null){
            model.addObject("message", message);
        }
        model.setViewName("view/login");
        return model;
    }

    @RequestMapping(value = "/hello")
    public String hello() {
        return "NewFile";
    }

    @RequestMapping(value = "/")
    public String index() {
        System.out.println("访问了后端 /  请求");
        return "view/login";
    }

    /**
     * 退出
     *
     * @return
     */
    @RequestMapping(value = "logout", method = RequestMethod.GET)
    public String logout(HttpServletRequest request) {

        //subject的实现类DelegatingSubject的logout方法，将本subject对象的session清空了
        //即使session托管给了redis ，redis有很多个浏览器的session
        //只要调用退出方法，此subject的、此浏览器的session就没了
        try {
            //退出
            SecurityUtils.getSubject().logout();

        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return "view/login";

    }

    @RequestMapping(value = "403")
    public String unAuth() {

        return "403";
    }


}
